package com.mi.soul.whale.common.Interceptor;

import com.mi.rule.auth.Public;
import com.mi.rule.util.project.MiException;
import com.mi.soul.whale.common.util.JwtKit;
import com.mi.soul.whale.common.util.ResMsg;
import com.mi.soul.whale.module.system.service.DictService;
import com.mi.soul.whale.module.system.service.SystemService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;


/**
 * 权限认证
 *
 * @author 王永吉
 */
@Slf4j
@Component
public class Auth implements HandlerInterceptor {
    @Autowired
    DictService dictService;
    @Autowired
    SystemService systemService;

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object object) {
        try {
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type,Token,Auth");
            if (request.getMethod().equals("OPTIONS")) return true;
            //权限认证开关
            if ("false".equals(dictService.getValue("enable_permission_authentication"))) return true;

            //检查权限
            return hasResource(request, object);
        }

        //已知异常
        catch (MiException e) {
            log.error(ExceptionUtils.getStackTrace(e));
            throw e;
        }

        //未知异常
        catch (Throwable e) {
            log.error(ExceptionUtils.getStackTrace(e));
            throw e;
        }

    }

    //校验权限
    private boolean hasResource(HttpServletRequest request, Object object) {
        if (object instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) object;
            String requestURI = request.getRequestURI();

            //方法的注解
            Public aPublic = handlerMethod.getMethod().getAnnotation(Public.class);

            //类的注解
            if (aPublic == null) {
                aPublic = handlerMethod.getMethod().getDeclaringClass().getAnnotation(Public.class);
            }

            //存在放行注解 @Public,执行放行
            if (aPublic != null) {
                log.info("{} 存在@Public注解 {}，直接放行", requestURI, aPublic.value());
                return true;
            }

            //路由符合放行条件
            if (requestURI.contains("/public/") || requestURI.contains("static/") || requestURI.contains("/static/")) {
                log.info("{} 路由符合放行条件，直接放行", requestURI);
                return true;
            }

            //权限校验
            String token = request.getHeader("Token");
            if (!JwtKit.check(token)) {
                log.info("{} 身份认证失败，Token不存在或已失效  Token: {}", requestURI, token);
                throw new MiException(ResMsg.ERROR_401);
            }

            //权限不足
            String roleId = JwtKit.roleId(token);
            List<String> resourceUrls = systemService.roleResourceUrls(roleId);
            if (!resourceUrls.contains(requestURI)) {
                log.info("请求被截拦 : " + requestURI + "  当前访问者无权访问该资源 ");
                throw new MiException(ResMsg.ERROR_402);
            }

            return false;
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object,
                                Exception exception) {
        //        System.out.println("7777777777777777777777777777777777777");
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object,
                           ModelAndView modelAndView) {
        //        System.out.println("888888888888888888888888888888888888888888888888");
    }


}
